#include "GameArea.h"
#include <QTimerEvent>
#include <QMessageBox>
#include <QKeyEvent>
#include <QTime>


#define RECT_COLUMES	15
#define RECT_ROWS		20
#define RECT_WIDTH		40
#define RECT_HEIGHT		40

//默认出生点 x方向
#define DEFAULT_BORN_POS_X    (RECT_COLUMES / 2 - 1)

GameArea::GameArea(QWidget *parent) : QWidget(parent)
{
    mScore = 0;
    mLevel = 1;

    setMinimumSize(RECT_COLUMES*RECT_WIDTH, RECT_ROWS*RECT_HEIGHT);
}

void GameArea::NewGame()
{
    mFixItems.mPoints.clear();


    //mCurItem 和 mNextItem 使用不同随机因子，避免初始一样
    mCurItem.InitNew(QTime::currentTime().msec());
    mCurItem.MoveTo(DEFAULT_BORN_POS_X, 1);

    mNextItem.InitNew(QTime::currentTime().second());
    emit sigUpdateNextItem(mNextItem.mType,mNextItem.mShape);

    mScore = 0;
    mLevel = 1;
    mTimerID = startTimer( GetLevelTime(mLevel) );
}

void GameArea::KeyPressed(int key)
//按键规则
{
    int x = 0;
    int y = 0;
    switch(key)
    {
    case Qt::Key_Left:
    {
        x = -1;
        break;
    }
    case Qt::Key_Up:
    {
        mCurItem.ChangeShape();
        if(HitSide() || HitBottom())
        {
            mCurItem.ChangeShape(-1);
        }
        return;
    }
    case Qt::Key_Right:
    {
        x = 1;
        break;
    }
    case Qt::Key_Down:
    {
        y = 1;
        break;
    }
    case Qt::Key_Space:
    {
        //空格键直接移到底部
        while(1)
        {
            mCurItem.Move(0,1);
            if(HitSide() || HitBottom())
            {
                mCurItem.Move(0,-1);
                break;
            }
        }
        return;
    }
    }
    mCurItem.Move(x,y);

    if (HitSide() || HitBottom())
    {
        mCurItem.Move(-x,-y);
    }
}

void GameArea::paintEvent(QPaintEvent *)
{
    //绘制左侧游戏区域
    DrawBKRects();
    DrawFixedRects();
    DrawCurItem();

    update();
}

void GameArea::DrawBKRects()
{
    QPainter painter(this);
    painter.setBrush(QColor("#696969"));
    painter.setPen(Qt::NoPen);

    for(int i = 0;i<RECT_COLUMES; i++)
    {
        for (int j = 0; j<RECT_ROWS; j++)
        {
            if (i == 0 || i == RECT_COLUMES - 1 || j==0 || j==RECT_ROWS-1)
            {
                painter.drawRect( i*RECT_WIDTH,j*RECT_HEIGHT,RECT_WIDTH,RECT_HEIGHT);
            }
        }
    }
}

void GameArea::DrawFixedRects()
{
    QPainter painter(this);
    painter.setBrush(QColor("#D3D3D3"));
    painter.setPen(QPen(QColor(Qt::black),1));

    mFixItems.Draw(painter,0,0,RECT_WIDTH,RECT_HEIGHT);
}

void GameArea::DrawCurItem()
{
    QPainter painter(this);
    painter.setBrush(QColor("#FFDEAD"));
    painter.setPen(QPen(QColor(Qt::black),1));

    mCurItem.Draw(painter,0,0,RECT_WIDTH,RECT_HEIGHT);
}

bool GameArea::HitSide()
{
    for (int i = 0; i<mCurItem.mPoints.size(); i++)
    {
        QPoint pt = mCurItem.mPoints[i];
        if (pt.x() <= 0 || pt.x() >= RECT_COLUMES - 1)
        {
            return true;
        }
    }
    return false;
}

bool GameArea::HitBottom()
{
    for (int i = 0; i<mCurItem.mPoints.size(); i++)
    {
        QPoint pt = mCurItem.mPoints[i];
        if (pt.y() >= RECT_ROWS - 1)
        {
            return true;
        }
        if (mFixItems.mPoints.contains(pt))
        {
            return true;
        }
    }
    return false;
}

bool GameArea::HitTop()
{
    for (int i = 0; i<mFixItems.mPoints.size(); i++)
    {
        QPoint pt = mFixItems.mPoints[i];
        if (pt.y() <= 1)
        {
            return true;
        }
    }
    return false;
}



void GameArea::AddToFixedRects()
{
    mFixItems.AddPoints(mCurItem.mPoints);
}

void GameArea::DeleteFullRows()
{
    int nRowsDeleted = 0;
    for (int i = 1; i<RECT_ROWS-1; i++)
    {
        int nCount = 0;
        for (int j = 1; j<RECT_COLUMES-1; j++)
        {
            if (mFixItems.mPoints.contains(QPoint(j,i)))
            {
                nCount++;
            }
        }
        if (nCount >= RECT_COLUMES-2)
        {
            mFixItems.DeleteRow(i);
            mFixItems.MoveDown(i,1);	//消除行之上的内容下移一个单位
            nRowsDeleted++;
        }
    }

    //一次元素落下，最多可能消4行
    //一次消除的越多，得分越多
    if (nRowsDeleted == 1)
    {
        mScore += 100;
    }
    else if (nRowsDeleted == 2)
    {
        mScore += 300;
    }
    else if (nRowsDeleted == 3)
    {
        mScore += 500;
    }
    else if (nRowsDeleted == 4)
    {
        mScore += 700;
    }
    emit sigUpdateScore(mScore);    //更新MainWindow界面得分

    //粗略使用每1000分一关
    if(mScore >= 1000 * mLevel)
    {
        mLevel++;

        //随关卡增加下落速度，即把定时器加快
        killTimer(mTimerID);
        mTimerID = startTimer( GetLevelTime(mLevel) );

        emit sigUpdateLevel(mLevel);    //更新MainWindow界面关卡
    }
}


int GameArea::GetLevelTime(int level)
{
    //第1关=1000ms,第2关=900ms 越来越快 第8关=300ms
    //关卡>8后，速度不再增加，保持200ms
    if(level > 8)
    {
        return 200;
    }
    if (level > 0)
    {
        return (11 - level) * 100;
    }
}



